Following and Preceding XPath in Selenium
Following and Preceding XPath are advanced XPath axes used in Selenium to locate web elements based on their relationship with other elements in the HTML DOM. They are especially useful when the target element does not have a unique ID, name, class, or other reliable attribute.
XPath axes allow Selenium testers to move through the DOM and identify elements according to their position and relationship with other nodes. The following axis selects nodes that appear after the current node in the document, while the preceding axis selects nodes that appear before the current node.
For complete Selenium learning and automation testing training, you can explore JustAcademy Selenium Training and register for a course demonstration through JustAcademy Course Demo Registration.
1. What is XPath?
XPath stands for XML Path Language. In Selenium, XPath is commonly used to locate elements inside an HTML document. XPath can identify elements using tags, attributes, text, relationships, indexes, and DOM positions.
XPath becomes particularly useful when normal locators such as ID, name, or class are unavailable or when web applications contain dynamic elements.
Basic XPath Syntax
//tagname[@attribute='value']
Example:
//input[@id='username']
This XPath locates an input element whose ID is username.
2. What are XPath Axes?
XPath axes define the relationship between the current node and other nodes in the DOM tree. They allow testers to navigate from one element to another element based on structural relationships.
Common XPath axes include:
- parent
- child
- ancestor
- descendant
- following
- preceding
- following-sibling
- preceding-sibling
- self
- ancestor-or-self
- descendant-or-self
Among these axes, following and preceding are useful when the required element is located before or after another known element in the document structure.
3. What is Following XPath?
The following XPath axis selects all nodes that appear after the current node in the document order, excluding descendants of the current node.
In simple words, if you know one element but cannot directly identify another element that comes after it, you can use the following axis to locate that element.
Syntax
//currentElement/following::targetElement
Example:
//input[@id='username']/following::input
This XPath starts from the input element with ID username and searches for input elements that appear later in document order.
4. Understanding the Following Axis
Consider the following HTML structure:
<div>
<input id="username">
<input id="email">
<input id="password">
<button>Login</button>
</div>
If the username field is known but the email field does not have a reliable locator, you can use:
//input[@id='username']/following::input[1]
The XPath starts from the username input and searches for the first input element appearing after it.
Important Point
The following axis is not limited to elements having the same parent. It can navigate to elements appearing later in the document order.
5. Following XPath with Attributes
You can combine the following axis with attributes to make the XPath more specific.
//input[@name='username']/following::input[@name='password']
This searches for an input with the name password that appears after the username input.
Another example:
//label[@for='username']/following::input[1]
This can be useful when a label is easier to identify than the input field itself.
6. Following XPath with Text
The text() function can be combined with the following axis when visible text provides a stable reference.
//label[text()='Username']/following::input[1]
This XPath finds the first input element appearing after the label containing the text Username.
Another example:
//h2[text()='Personal Information']/following::input[1]
This locates the first input element appearing after the heading containing Personal Information.
7. Following XPath with Index
When multiple elements are returned by a following-axis expression, an index can be used to select a specific element.
//input[@id='username']/following::input[1]
The [1] selects the first matching input element in the result.
Example:
//input[@id='username']/following::input[2]
The [2] selects the second matching input element.
Indexes should be used carefully because changes in page structure can change the order of matching elements.
8. What is Preceding XPath?
The preceding XPath axis selects nodes that appear before the current node in document order, excluding ancestors of the current node.
In simple words, if you can identify an element that comes later in the document but the target element appears before it, the preceding axis can be used to navigate backward.
Syntax
//currentElement/preceding::targetElement
Example:
//input[@id='password']/preceding::input
This XPath searches for input elements that appear before the password input in document order.
9. Understanding the Preceding Axis
Consider this HTML:
<div>
<input id="username">
<input id="email">
<input id="password">
<button>Login</button>
</div>
If the password input is easy to identify but the email input does not have a unique attribute, you can use:
//input[@id='password']/preceding::input[1]
The XPath searches backward from the password input and selects a matching input element that appears before it.
10. Preceding XPath with Attributes
You can combine the preceding axis with attributes.
//input[@name='password']/preceding::input[@name='username']
This searches for a username input appearing before the password input.
Another example:
//button[@id='submit']/preceding::input[@type='email']
This searches for an email input appearing before the submit button.
11. Preceding XPath with Text
Text-based XPath can also be combined with the preceding axis.
//button[text()='Submit']/preceding::input[1]
This searches for the first matching input that appears before the Submit button.
Another example:
//h2[text()='Payment Details']/preceding::input[1]
This can locate an input appearing before the Payment Details heading.
12. Following vs Preceding
| Feature | Following | Preceding |
| Direction | Moves forward | Moves backward |
| Document position | Elements after current node | Elements before current node |
| Typical use | Find an element located after a known element | Find an element located before a known element |
| Syntax | following:: | preceding:: |
| Navigation | Forward through document order | Backward through document order |
13. Following vs Following-Sibling
following and following-sibling are different XPath axes.
The following axis searches elements appearing later in the document, while following-sibling searches only sibling elements that share the same parent.
Following
//div[@id='first']/following::div
Following-Sibling
//div[@id='first']/following-sibling::div
Use following-sibling when the target is specifically a sibling of the current element. Use following when the target may exist elsewhere later in the document.
14. Preceding vs Preceding-Sibling
Similarly, preceding and preceding-sibling are different.
Preceding
//div[@id='last']/preceding::div
Preceding-Sibling
//div[@id='last']/preceding-sibling::div
The preceding-sibling axis only searches siblings of the current node, while preceding can navigate to nodes earlier in document order.
15. Following with Parent Relationship
Following can be combined with parent navigation to locate related elements.
//label[text()='Username']/parent::div/following::div[1]
This first moves from the label to its parent and then searches for a div appearing later in the document.
16. Preceding with Parent Relationship
The preceding axis can also be combined with parent relationships.
//input[@id='password']/parent::div/preceding::div[1]
This first moves to the parent div and then searches backward for a preceding div.
17. Following with Descendant Elements
Following can be combined with descendant navigation when the target exists inside a later container.
//h2[text()='Products']/following::div[1]//button
This identifies a div appearing after the Products heading and then searches inside that div for a button.
18. Preceding with Descendant Elements
The same approach can be used in the reverse direction.
//button[text()='Checkout']/preceding::div[1]//input
This searches backward for a preceding div and then searches inside it for input elements.
19. Following XPath in Login Forms
Following XPath is useful in login forms when labels or headings are easier to identify than form controls.
<label>Username</label>
<input type="text">
<label>Password</label>
<input type="password">
Example:
//label[text()='Username']/following::input[1]
For password:
//label[text()='Password']/following::input[1]
20. Preceding XPath in Login Forms
If the password field is easy to identify and you need an earlier input field, preceding can be used.
//input[@type='password']/preceding::input[1]
This searches for an input appearing before the password field.
21. Following XPath in E-Commerce Applications
E-commerce websites frequently contain repeated products, prices, buttons, and product cards. Following XPath can help navigate between related elements when the DOM structure is complex.
Example:
//h3[text()='Laptop']/following::button[text()='Add to Cart'][1]
This searches for an Add to Cart button appearing after the Laptop heading.
Another example:
//span[text()='Wireless Mouse']/following::button[contains(text(),'Cart')][1]
This can locate a cart-related button after a product name.
22. Preceding XPath in E-Commerce Applications
Preceding XPath can be useful when the product name or price is located before a button or other element.
//button[text()='Add to Cart']/preceding::h3[1]
This searches backward for the nearest matching heading before the Add to Cart button.
23. Following XPath in Tables
Tables can contain rows and columns where direct attributes are not always unique. XPath axes can help navigate from known table content to related elements.
//td[text()='John']/following-sibling::td[1]
For elements outside the immediate sibling relationship, following can be used:
//td[text()='John']/following::td[1]
The exact axis should be selected according to the structure of the table.
24. Preceding XPath in Tables
Preceding can be used when the target table element occurs earlier in the document.
//td[text()='Completed']/preceding::td[1]
This searches backward for a preceding table cell.
25. Following XPath with Contains()
The contains() function can make an XPath more flexible when the complete attribute value is dynamic.
//div[contains(@class,'product')]/following::button[contains(@class,'cart')][1]
This finds a cart-related button after a product-related div.
26. Preceding XPath with Contains()
//button[contains(@class,'submit')]/preceding::input[contains(@name,'email')][1]
This searches backward from a submit button for an email-related input.
27. Following XPath with Starts-With()
The starts-with() function can be used when an attribute begins with a known value.
//input[starts-with(@id,'user')]/following::input[1]
This identifies an input whose ID begins with user and then searches for a following input.
28. Preceding XPath with Starts-With()
//button[starts-with(@id,'submit')]/preceding::input[1]
This searches backward from a button whose ID starts with submit.
29. Following XPath with Multiple Conditions
Multiple conditions can be combined using and and or.
//input[@type='text' and @name='username']/following::input[@type='password'][1]
This starts from a username input satisfying two conditions and searches for a following password input.
30. Preceding XPath with Multiple Conditions
//button[@type='submit' and contains(@class,'login')]/preceding::input[@type='text'][1]
This searches backward from a login submit button for the first matching text input.
31. Using Following and Preceding with Selenium WebDriver
After creating an XPath, Selenium can use the By.xpath() locator to identify the element.
WebElement passwordField = driver.findElement(
By.xpath("//label[text()='Password']/following::input[1]")
);
passwordField.sendKeys("Password@123");
Example using preceding:
WebElement usernameField = driver.findElement(
By.xpath("//input[@type='password']/preceding::input[1]")
);
usernameField.sendKeys("testuser");
32. Complete Selenium Example
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class FollowingPrecedingExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.get("https://example.com");
WebElement password = driver.findElement(
By.xpath("//label[text()='Password']/following::input[1]")
);
password.sendKeys("Password@123");
WebElement username = driver.findElement(
By.xpath("//input[@type='password']/preceding::input[1]")
);
username.sendKeys("testuser");
driver.quit();
}
}
33. Following and Preceding with Explicit Wait
Dynamic websites may load elements after the initial page load. In such situations, explicit waits can be used before interacting with elements.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement password = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//label[text()='Password']/following::input[1]")
)
);
password.sendKeys("Password@123");
Explicit waits help synchronize the test with the application's actual state instead of relying only on fixed delays.
34. Following and Preceding in Dynamic Web Applications
Modern web applications can generate dynamic IDs, classes, and containers. In such applications, a tester may identify a stable element and navigate to the required dynamic element using XPath relationships.
For example:
//label[contains(text(),'Email')]/following::input[1]
Instead of depending on a generated ID, the XPath uses visible label text as the reference point.
35. Following and Preceding in Forms
Form layouts often contain labels followed by input controls. Following XPath is useful for this pattern.
//label[text()='Email']/following::input[1]
For reverse navigation:
//input[@type='email']/preceding::label[1]
The second XPath searches for a label that occurs before the email input.
36. Following and Preceding in Registration Forms
//label[text()='First Name']/following::input[1]
//label[text()='Last Name']/following::input[1]
//label[text()='Email']/following::input[1]
//label[text()='Password']/following::input[1]
These expressions can be useful when the labels are stable but the input attributes are dynamic.
37. Following and Preceding with normalize-space()
The normalize-space() function removes leading and trailing whitespace and normalizes consecutive whitespace characters.
//label[normalize-space()='Username']/following::input[1]
For reverse navigation:
//input[@type='password']/preceding::label[normalize-space()='Password'][1]
This is useful when HTML formatting contains unwanted whitespace around visible text.
38. Difference Between Following and Descendant
| Axis | Meaning |
| following | Selects nodes appearing later in document order, excluding descendants |
| descendant | Selects nodes inside the current node at any depth |
Example:
//div[@id='container']/descendant::button
Following example:
//div[@id='container']/following::button
39. Difference Between Preceding and Ancestor
| Axis | Meaning |
| preceding | Selects nodes appearing earlier in document order, excluding ancestors |
| ancestor | Selects parent, grandparent, and higher-level elements of the current node |
Example:
//input[@id='email']/ancestor::form
Preceding example:
//input[@id='email']/preceding::h2
40. How to Test XPath in Chrome DevTools
Chrome DevTools provides a convenient way to test XPath expressions before adding them to Selenium code.
- Open the webpage in Chrome.
- Press F12 or right-click and select Inspect.
- Open the Console tab.
- Use the $x() function.
- Enter the XPath expression.
$x("//label[text()='Username']/following::input[1]")
For preceding:
$x("//input[@type='password']/preceding::input[1]")
The returned elements can then be inspected to verify whether the XPath identifies the intended element.
41. Common Mistakes with Following XPath
- Confusing following with following-sibling.
- Using a broad XPath that returns many elements.
- Using indexes unnecessarily.
- Depending on unstable text or attributes.
- Ignoring the actual DOM structure.
- Not testing the XPath in browser DevTools.
- Using a following axis when a direct child or sibling relationship would be more appropriate.
42. Common Mistakes with Preceding XPath
- Confusing preceding with preceding-sibling.
- Assuming preceding searches only siblings.
- Using a broad expression that matches multiple elements.
- Using unstable indexes.
- Not checking document order.
- Ignoring dynamic DOM changes.
- Creating unnecessarily complicated XPath expressions.
43. Best Practices for Following and Preceding XPath
- Start with a stable reference element.
- Use meaningful attributes whenever possible.
- Use text carefully because visible text can change.
- Prefer shorter XPath expressions when they remain reliable.
- Use following-sibling when the target is specifically a sibling.
- Use preceding-sibling when the target is specifically a previous sibling.
- Use indexes only when necessary.
- Test XPath expressions in browser DevTools.
- Use explicit waits for dynamically loaded elements.
- Avoid absolute XPath when relative XPath can be used.
- Review XPath whenever the application's DOM structure changes.
44. Real-World Example: Login Page
Suppose a login page contains the following structure:
<div class="form-group">
<label>Username</label>
<input type="text">
</div>
<div class="form-group">
<label>Password</label>
<input type="password">
</div>
<button>Login</button>
Username field:
//label[text()='Username']/following::input[1]
Password field:
//label[text()='Password']/following::input[1]
Previous input from the Login button:
//button[text()='Login']/preceding::input[1]
45. Real-World Example: Product Page
Suppose a product page displays a product name followed by price and an Add to Cart button.
<h3>Laptop</h3>
<span>$800</span>
<button>Add to Cart</button>
Find the price after the product name:
//h3[text()='Laptop']/following::span[1]
Find the Add to Cart button:
//h3[text()='Laptop']/following::button[1]
Find the product name before the Add to Cart button:
//button[text()='Add to Cart']/preceding::h3[1]
46. Real-World Example: Registration Page
Consider a registration page where labels are stable but generated input IDs change.
//label[normalize-space()='Email']/following::input[1]
This approach can be more useful than relying on a generated ID such as input_92837.
Reverse navigation can be performed using:
//input[@type='email']/preceding::label[1]
47. When Should You Use Following?
- When the target element appears after a known reference element.
- When the target has weak or dynamic attributes.
- When a stable label can be used as a reference.
- When direct parent-child navigation is not sufficient.
- When the target is not necessarily a sibling.
48. When Should You Use Preceding?
- When the target element appears before a known reference element.
- When the later element has a more stable locator.
- When reverse DOM navigation is required.
- When a target cannot easily be located using its own attributes.
- When the relationship with a later element is more stable than the target's direct locator.
49. Following and Preceding XPath Interview Questions
- What is the following XPath axis?
- What is the preceding XPath axis?
- What is the difference between following and following-sibling?
- What is the difference between preceding and preceding-sibling?
- Does following search descendants?
- Does preceding include ancestors?
- How do you locate an input after a label using XPath?
- How do you locate an element before a button?
- How can you use following with contains()?
- How can you use preceding with normalize-space()?
- How do you select the first element returned by a following XPath?
- How do you test following XPath in Chrome DevTools?
- How can following and preceding help with dynamic elements?
- What is the difference between following and descendant?
- What is the difference between preceding and ancestor?
50. Interview Example Questions with Answers
Q1. What is following in XPath?
The following axis selects nodes that occur after the current node in document order, excluding descendants of the current node.
Q2. What is preceding in XPath?
The preceding axis selects nodes that occur before the current node in document order, excluding ancestors of the current node.
Q3. Give an example of following XPath.
//label[text()='Email']/following::input[1]
Q4. Give an example of preceding XPath.
//button[text()='Submit']/preceding::input[1]
Q5. What is the difference between following and following-sibling?
Following can select nodes appearing later in document order, while following-sibling selects only sibling nodes that share the same parent.
Q6. What is the difference between preceding and preceding-sibling?
Preceding selects nodes appearing earlier in document order, while preceding-sibling selects only previous sibling nodes of the current element.
51. Following and Preceding XPath Cheat Sheet
| Requirement | XPath |
| Element after current element | //element/following::tag |
| Element before current element | //element/preceding::tag |
| First following element | //element/following::tag[1] |
| First preceding element | //element/preceding::tag[1] |
| Following input after label | //label/following::input[1] |
| Input before button | //button/preceding::input[1] |
| Following with text | //label[text()='Email']/following::input[1] |
| Preceding with text | //button[text()='Submit']/preceding::input[1] |
| Following with contains | //div[contains(@class,'product')]/following::button[1] |
| Preceding with contains | //button[contains(@class,'submit')]/preceding::input[1] |
52. Practical Checklist
- Identify a stable reference element.
- Determine whether the target is before or after the reference.
- Use following:: when moving forward.
- Use preceding:: when moving backward.
- Use following-sibling:: for same-parent forward siblings.
- Use preceding-sibling:: for same-parent backward siblings.
- Add attributes or text to narrow the XPath.
- Use [1] when the first matching element is required.
- Test the XPath using Chrome DevTools.
- Use explicit waits for dynamic elements.
- Avoid unnecessarily long XPath expressions.
- Recheck locators when the application's DOM changes.
53. Conclusion
Following and preceding are powerful XPath axes for navigating complex web pages in Selenium. The following axis helps locate elements that occur after a reference node, while the preceding axis helps locate elements that occur before it.
These axes are especially useful for forms, tables, product pages, dynamic web applications, and situations where the target element does not have a stable unique locator. Understanding the difference between following, preceding, following-sibling, and preceding-sibling helps testers create more accurate and maintainable XPath expressions.
For structured Selenium automation training, practical projects, WebDriver, XPath, TestNG, Page Object Model, framework development, and interview preparation, visit JustAcademy Selenium Training.
To explore the available course demonstration option, visit JustAcademy Course Demo Registration.